﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HalconDotNet;
using System.Windows.Forms;

namespace PylonLiveView
{
    class TinDetection
    {
        public HObject TD_image1;
        public HTuple TD_Message;

        public void action(HObject xx1)
        {


            // Local iconic variables 

            HObject ho_Image, ho_GrayImage, ho_RegionROI;
            HObject ho_RegionErosionROI, ho_ConnectedRegions, ho_SelectedRegions2;
            HObject ho_RegionTrans, ho_ImageROI, ho_RegionIC, ho_RegionDilationIC;
            HObject ho_ConnectedRegionsIC, ho_SelectedRegionsIC, ho_RectangleIC;
            HObject ho_ImageAffinTransROI, ho_RegionAffineTransIC, ho_ImageReducedIC;
            HObject ho_ImageAffinTransIC, ho_RegionPartIC, ho_RectanglePartIC;
            HObject ho_RectangleBody, ho_RegionLeads, ho_RegionErosion;
            HObject ho_ConnectedRegionsLeads, ho_SelectedRegionsLeads = null;

            // Local control variables 

            HTuple hv_Width = null, hv_Height = null, hv_Ratio = null;
            HTuple hv_Max_area = null, hv_WindowHandle = null, hv_Row = null;
            HTuple hv_Column = null, hv_Phi = null, hv_Length1 = null;
            HTuple hv_Length2 = null, hv_HomMat2D = null, hv_RowPartIC = null;
            HTuple hv_ColumnPartIC = null, hv_Phi_PartIC = null, hv_Length1_PartIC = null;
            HTuple hv_Length2_PartIC = null, hv_WidthIC = null, hv_HeightIC = null;
            HTuple hv_Mean = null, hv_Deviation = null, hv_MeasureHandle = null;
            HTuple hv_RowEdge = null, hv_ColumnEdge = null, hv_Amplitude = null;
            HTuple hv_Distance = null, hv_Body = null, hv_Area = null;
            HTuple hv_Row1 = null, hv_Column1 = null, hv_Median = null;
            HTuple hv_shorter = null, hv_IndexShorter = null, hv_ShorterSum = null;
            HTuple hv_IndexArea = null, hv_Shorter = new HTuple();
            HTuple hv_MaxArea = new HTuple(), hv_MinArea = new HTuple();
            HTuple hv_Message = new HTuple();
            // Initialize local and output iconic variables 
            HOperatorSet.GenEmptyObj(out ho_Image);
            HOperatorSet.GenEmptyObj(out ho_GrayImage);
            HOperatorSet.GenEmptyObj(out ho_RegionROI);
            HOperatorSet.GenEmptyObj(out ho_RegionErosionROI);
            HOperatorSet.GenEmptyObj(out ho_ConnectedRegions);
            HOperatorSet.GenEmptyObj(out ho_SelectedRegions2);
            HOperatorSet.GenEmptyObj(out ho_RegionTrans);
            HOperatorSet.GenEmptyObj(out ho_ImageROI);
            HOperatorSet.GenEmptyObj(out ho_RegionIC);
            HOperatorSet.GenEmptyObj(out ho_RegionDilationIC);
            HOperatorSet.GenEmptyObj(out ho_ConnectedRegionsIC);
            HOperatorSet.GenEmptyObj(out ho_SelectedRegionsIC);
            HOperatorSet.GenEmptyObj(out ho_RectangleIC);
            HOperatorSet.GenEmptyObj(out ho_ImageAffinTransROI);
            HOperatorSet.GenEmptyObj(out ho_RegionAffineTransIC);
            HOperatorSet.GenEmptyObj(out ho_ImageReducedIC);
            HOperatorSet.GenEmptyObj(out ho_ImageAffinTransIC);
            HOperatorSet.GenEmptyObj(out ho_RegionPartIC);
            HOperatorSet.GenEmptyObj(out ho_RectanglePartIC);
            HOperatorSet.GenEmptyObj(out ho_RectangleBody);
            HOperatorSet.GenEmptyObj(out ho_RegionLeads);
            HOperatorSet.GenEmptyObj(out ho_RegionErosion);
            HOperatorSet.GenEmptyObj(out ho_ConnectedRegionsLeads);
            HOperatorSet.GenEmptyObj(out ho_SelectedRegionsLeads);
            try
            {
                // dev_update_window(...); only in hdevelop
                if (HDevWindowStack.IsOpen())
                {
                    //dev_close_window ()
                }
                ho_Image.Dispose();
                ho_Image = xx1;
                //HOperatorSet.ReadImage(out ho_Image, "C:/Users/于立昆/Desktop/image2/12");
                HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
                hv_Ratio = 0.25;
                hv_Max_area = hv_Width * hv_Height;
                //dev_open_window (0, 0, Width*Ratio, Height*Ratio, 'black', WindowHandle)
                if (HDevWindowStack.IsOpen())
                {
                    HOperatorSet.DispObj(ho_Image, HDevWindowStack.GetActive());
                }
                //*选出亮区域
                ho_GrayImage.Dispose();
                HOperatorSet.Rgb1ToGray(ho_Image, out ho_GrayImage);
                ho_RegionROI.Dispose();
                HOperatorSet.Threshold(ho_GrayImage, out ho_RegionROI, 220, 255);
                ho_RegionErosionROI.Dispose();
                HOperatorSet.ErosionCircle(ho_RegionROI, out ho_RegionErosionROI, 25);
                ho_ConnectedRegions.Dispose();
                HOperatorSet.Connection(ho_RegionErosionROI, out ho_ConnectedRegions);
                ho_SelectedRegions2.Dispose();
                HOperatorSet.SelectShapeStd(ho_ConnectedRegions, out ho_SelectedRegions2, "max_area",
                    70);
                ho_RegionTrans.Dispose();
                HOperatorSet.ShapeTrans(ho_SelectedRegions2, out ho_RegionTrans, "convex");
                ho_ImageROI.Dispose();
                HOperatorSet.ReduceDomain(ho_GrayImage, ho_RegionTrans, out ho_ImageROI);
                //选出暗区域即芯片区域
                ho_RegionIC.Dispose();
                HOperatorSet.Threshold(ho_ImageROI, out ho_RegionIC, 0, 240);
                ho_RegionDilationIC.Dispose();
                HOperatorSet.DilationRectangle1(ho_RegionIC, out ho_RegionDilationIC, 3, 3);
                ho_ConnectedRegionsIC.Dispose();
                HOperatorSet.Connection(ho_RegionDilationIC, out ho_ConnectedRegionsIC);

                ho_SelectedRegionsIC.Dispose();
                HOperatorSet.SelectShapeStd(ho_ConnectedRegionsIC, out ho_SelectedRegionsIC,
                    "max_area", 70);
                //画出芯片最小外接矩形
                HOperatorSet.SmallestRectangle2(ho_SelectedRegionsIC, out hv_Row, out hv_Column,
                    out hv_Phi, out hv_Length1, out hv_Length2);
                ho_RectangleIC.Dispose();
                HOperatorSet.GenRectangle2(out ho_RectangleIC, hv_Row, hv_Column, hv_Phi, hv_Length1,
                    hv_Length2);
                ho_RegionDilationIC.Dispose();
                HOperatorSet.DilationRectangle1(ho_RectangleIC, out ho_RegionDilationIC, 10,
                    10);

                //仿射变换，将芯片转正
                HOperatorSet.VectorAngleToRigid(hv_Row, hv_Column, hv_Phi, hv_Row, hv_Column,
                    (new HTuple(0)).TupleRad(), out hv_HomMat2D);
                ho_ImageAffinTransROI.Dispose();
                HOperatorSet.AffineTransImage(ho_ImageROI, out ho_ImageAffinTransROI, hv_HomMat2D,
                    "constant", "false");
                ho_RegionAffineTransIC.Dispose();
                HOperatorSet.AffineTransRegion(ho_SelectedRegionsIC, out ho_RegionAffineTransIC,
                    hv_HomMat2D, "nearest_neighbor");

                HOperatorSet.SmallestRectangle2(ho_RegionAffineTransIC, out hv_RowPartIC, out hv_ColumnPartIC,
                    out hv_Phi_PartIC, out hv_Length1_PartIC, out hv_Length2_PartIC);

                ho_RegionAffineTransIC.Dispose();
                HOperatorSet.GenRectangle2(out ho_RegionAffineTransIC, hv_RowPartIC, hv_ColumnPartIC,
                    hv_Phi_PartIC, hv_Length1_PartIC, hv_Length2_PartIC);
                ho_RegionDilationIC.Dispose();
                HOperatorSet.DilationRectangle1(ho_RegionAffineTransIC, out ho_RegionDilationIC,
                    50, 50);

                ho_ImageReducedIC.Dispose();
                HOperatorSet.ReduceDomain(ho_ImageAffinTransROI, ho_RegionDilationIC, out ho_ImageReducedIC
                    );
                ho_ImageAffinTransIC.Dispose();
                HOperatorSet.CropDomain(ho_ImageReducedIC, out ho_ImageAffinTransIC);
                if (HDevWindowStack.IsOpen())
                {
                    HOperatorSet.ClearWindow(HDevWindowStack.GetActive());
                }
                if (HDevWindowStack.IsOpen())
                {
                    HOperatorSet.DispObj(ho_ImageAffinTransIC, HDevWindowStack.GetActive());
                }
                HOperatorSet.GetImageSize(ho_ImageAffinTransIC, out hv_WidthIC, out hv_HeightIC);

                HOperatorSet.SetWindowAttr("background_color", "black");
                HOperatorSet.OpenWindow(0, 0, hv_WidthIC, hv_HeightIC, 0, "invisible", "", out hv_WindowHandle);
                HDevWindowStack.Push(hv_WindowHandle);
                if (HDevWindowStack.IsOpen())
                {
                    HOperatorSet.SetPart(HDevWindowStack.GetActive(), 0, 0, hv_WidthIC, hv_HeightIC);
                }






                //reduce_domain (ImageROI, RegionDilationIC, ImageReducedIC)
                //crop_domain (ImageReducedIC, ImagePartIC)
                if (HDevWindowStack.IsOpen())
                {
                    //dev_display (ImagePartIC)
                }
                //get_image_size (ImagePartIC, WidthIC, HeightIC)


                //对裁剪出的芯片处理-只画出芯片区域
                if (HDevWindowStack.IsOpen())
                {
                    HOperatorSet.SetDraw(HDevWindowStack.GetActive(), "margin");
                }
                if (HDevWindowStack.IsOpen())
                {
                    HOperatorSet.SetColor(HDevWindowStack.GetActive(), "red");
                }
                ho_RegionPartIC.Dispose();
                HOperatorSet.Threshold(ho_ImageAffinTransIC, out ho_RegionPartIC, 0, 200);
                HOperatorSet.SmallestRectangle2(ho_RegionPartIC, out hv_RowPartIC, out hv_ColumnPartIC,
                    out hv_Phi_PartIC, out hv_Length1_PartIC, out hv_Length2_PartIC);

                //仿射变换
                //vector_angle_to_rigid (RowPartIC, ColumnPartIC, Phi_PartIC, RowPartIC, ColumnPartIC, rad(0), HomMat2D)
                //affine_trans_image (ImagePartIC, ImageAffinTrans, HomMat2D, 'constant', 'false')
                //affine_trans_region (RegionPartIC, RegionAffineTrans, HomMat2D, 'nearest_neighbor')

                //获得测量矩形
                ho_RectanglePartIC.Dispose();
                HOperatorSet.GenRectangle2(out ho_RectanglePartIC, hv_RowPartIC, hv_ColumnPartIC,
                    0, hv_Length1_PartIC + 5, hv_Length2_PartIC * 0.5);
                HOperatorSet.Intensity(ho_RectanglePartIC, ho_ImageAffinTransIC, out hv_Mean,
                    out hv_Deviation);
                //获得测量句柄
                HOperatorSet.GenMeasureRectangle2(hv_RowPartIC, hv_ColumnPartIC, 0, hv_Length1_PartIC + 5,
                    20, hv_WidthIC, hv_HeightIC, "nearest_neighbor", out hv_MeasureHandle);
                //测量芯片宽度引脚长度

                HOperatorSet.MeasurePos(ho_ImageAffinTransIC, hv_MeasureHandle, 1, 30, "all",
                    "all", out hv_RowEdge, out hv_ColumnEdge, out hv_Amplitude, out hv_Distance);
                HOperatorSet.TupleMax(hv_Distance, out hv_Body);
                //显示测量结果
                if (HDevWindowStack.IsOpen())
                {
                    HOperatorSet.SetColor(HDevWindowStack.GetActive(), "red");
                }
                if (HDevWindowStack.IsOpen())
                {
                    //dev_display (ImageAffinTransIC)
                }

                //disp_line (200000, RowEdge-100, ColumnEdge, RowEdge+100, ColumnEdge)
                //if (|Distance|>3)
                //tuple_sort (Distance, SortedDistance)
                //tuple_sort_index (Distance, IndicesDistance)
                //*     tuple_remove (Distance, IndicesDistance[0:|Distance|-4], NewDistance)

                //*     for i := 0 to |NewDistance|-1 by 1
                //set_display_font (WindowHandle, Body/40, 'mono', 'true', 'false')
                //string := ['左侧引脚长度：','芯片封装宽度：','右侧引脚长度：']
                //*     disp_message (200000, string[i]+NewDistance[i]$'.2f', 'ImagePart', RowEdge[0]+i*(Body/6), ColumnEdge[0]+Body/6, 'yellow', 'false')
                //*     endfor
                //elseif (|Distance|=3)
                //for i := 0 to |Distance|-1 by 1
                //set_display_font (WindowHandle, Body/40, 'mono', 'true', 'false')
                //string := ['左侧引脚长度：','芯片封装宽度：','右侧引脚长度：']
                //*         disp_message (200000, string[i]+Distance[i]$'.2f', 'ImageAffinTrans', RowEdge[0]+i*(Body/6), ColumnEdge[0]+Body/6, 'yellow', 'false')
                //endfor
                //else
                //set_display_font (WindowHandle, Body/40, 'mono', 'true', 'false')
                //disp_message (200000, '未检测到引脚', 'ImageAffinTrans', RowPartIC, ColumnPartIC-2.5*(Body/40), 'red', 'false')
                //endif

                HOperatorSet.CloseMeasure(hv_MeasureHandle);
                //确定封装本体矩形

                ho_RectangleBody.Dispose();
                HOperatorSet.GenRectangle2(out ho_RectangleBody, hv_RowPartIC, hv_ColumnPartIC,
                    0, (hv_Body * 0.5) + 10, (hv_Body * 0.5) + 10);
                //去掉封装本体
                ho_RegionLeads.Dispose();
                HOperatorSet.Difference(ho_RegionPartIC, ho_RectangleBody, out ho_RegionLeads
                    );
                ho_RegionErosion.Dispose();
                HOperatorSet.ErosionRectangle1(ho_RegionLeads, out ho_RegionErosion, 2.5, 2.5);
                ho_ConnectedRegionsLeads.Dispose();
                HOperatorSet.Connection(ho_RegionErosion, out ho_ConnectedRegionsLeads);
                //计算每一个连通域的面积
                HOperatorSet.AreaCenter(ho_ConnectedRegionsLeads, out hv_Area, out hv_Row1,
                    out hv_Column1);
                HOperatorSet.TupleMedian(hv_Area, out hv_Median);

                hv_shorter = new HTuple();
                hv_IndexShorter = 0;
                hv_ShorterSum = 0;
                for (hv_IndexArea = 0; (int)hv_IndexArea <= (int)((new HTuple(hv_Area.TupleLength()
                    )) - 1); hv_IndexArea = (int)hv_IndexArea + 1)
                {
                    if ((int)(new HTuple(((hv_Area.TupleSelect(hv_IndexArea))).TupleGreater(hv_Median * 1.5))) != 0)
                    {
                        hv_ShorterSum = hv_ShorterSum + 1;
                        if (hv_Shorter == null)
                            hv_Shorter = new HTuple();
                        hv_Shorter[hv_IndexShorter] = hv_Area.TupleSelect(hv_IndexArea);
                        hv_IndexShorter = hv_IndexShorter + 1;
                        HOperatorSet.TupleMax(hv_Shorter, out hv_MaxArea);
                        HOperatorSet.TupleMin(hv_Shorter, out hv_MinArea);
                        ho_SelectedRegionsLeads.Dispose();
                        HOperatorSet.SelectShape(ho_ConnectedRegionsLeads, out ho_SelectedRegionsLeads,
                            "area", "and", hv_MinArea, hv_MaxArea);
                    }
                }


                // stop(...); only in hdevelop
                if (HDevWindowStack.IsOpen())
                {
                    //dev_clear_window ()
                }
                if (HDevWindowStack.IsOpen())
                {
                    HOperatorSet.DispObj(ho_ImageAffinTransIC, HDevWindowStack.GetActive());
                }

                if ((int)(new HTuple(hv_ShorterSum.TupleEqual(0))) != 0)
                {
                    //set_display_font (WindowHandle, Body/20, 'mono', 'true', 'false')
                    //disp_message (200000, '合 格', 'ImageAffinTrans', RowPartIC-Body/20, ColumnPartIC-Body/8, 'green', 'false')
                    TD_image1 = ho_ImageAffinTransIC;
                    TD_Message = "合 格";
                }
                else
                {
                    if (HDevWindowStack.IsOpen())
                    {
                        HOperatorSet.DispObj(ho_SelectedRegionsLeads, HDevWindowStack.GetActive()
                            );
                    }
                    //set_display_font (WindowHandle, Body/30, 'mono', 'true', 'false')
                    HOperatorSet.DumpWindowImage(out TD_image1, hv_WindowHandle);
                    hv_Message = "不 合 格";
                    //disp_message (200000, Message, 'ImageAffinTrans', RowPartIC-Body/8, ColumnPartIC-Body/8, 'red', 'false')
                    //set_display_font (WindowHandle, Body/60, 'mono', 'true', 'false')
                    if (HDevWindowStack.IsOpen())
                    {
                        //dev_set_color ('red')
                    }
                    if (hv_Message == null)
                        hv_Message = new HTuple();
                    hv_Message[1] = "共 有：";
                    if (hv_Message == null)
                        hv_Message = new HTuple();
                    hv_Message[2] = " 处短路";
                    //color := 'green'
                    //disp_message (200000, Message[1]+ShorterSum+Message[2], 'ImageAffinTrans', RowPartIC+Body/8, ColumnPartIC-Body/8, color, 'false')
                    TD_Message = hv_Message + "\r\n" + ((hv_Message.TupleSelect(1)) + hv_ShorterSum) + (hv_Message.TupleSelect(2));

                }




            }
            catch (HalconException HDevExpDefaultException)
            {
                ho_Image.Dispose();
                ho_GrayImage.Dispose();
                ho_RegionROI.Dispose();
                ho_RegionErosionROI.Dispose();
                ho_ConnectedRegions.Dispose();
                ho_SelectedRegions2.Dispose();
                ho_RegionTrans.Dispose();
                ho_ImageROI.Dispose();
                ho_RegionIC.Dispose();
                ho_RegionDilationIC.Dispose();
                ho_ConnectedRegionsIC.Dispose();
                ho_SelectedRegionsIC.Dispose();
                ho_RectangleIC.Dispose();
                ho_ImageAffinTransROI.Dispose();
                ho_RegionAffineTransIC.Dispose();
                ho_ImageReducedIC.Dispose();
                ho_ImageAffinTransIC.Dispose();
                ho_RegionPartIC.Dispose();
                ho_RectanglePartIC.Dispose();
                ho_RectangleBody.Dispose();
                ho_RegionLeads.Dispose();
                ho_RegionErosion.Dispose();
                ho_ConnectedRegionsLeads.Dispose();
                ho_SelectedRegionsLeads.Dispose();

                throw HDevExpDefaultException;
            }
            ho_Image.Dispose();
            ho_GrayImage.Dispose();
            ho_RegionROI.Dispose();
            ho_RegionErosionROI.Dispose();
            ho_ConnectedRegions.Dispose();
            ho_SelectedRegions2.Dispose();
            ho_RegionTrans.Dispose();
            ho_ImageROI.Dispose();
            ho_RegionIC.Dispose();
            ho_RegionDilationIC.Dispose();
            ho_ConnectedRegionsIC.Dispose();
            ho_SelectedRegionsIC.Dispose();
            ho_RectangleIC.Dispose();
            ho_ImageAffinTransROI.Dispose();
            ho_RegionAffineTransIC.Dispose();
            ho_ImageReducedIC.Dispose();
            //ho_ImageAffinTransIC.Dispose();
            ho_RegionPartIC.Dispose();
            ho_RectanglePartIC.Dispose();
            ho_RectangleBody.Dispose();
            ho_RegionLeads.Dispose();
            ho_RegionErosion.Dispose();
            ho_ConnectedRegionsLeads.Dispose();
            ho_SelectedRegionsLeads.Dispose();

        }




    }
}
